home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / demos / GL / libgobj / modify.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  9KB  |  470 lines

  1. /*
  2.  * Copyright 1984, 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17.  
  18.  
  19. #include "gobj.h"
  20.  
  21. #include <gl.h>
  22. #include <math.h>
  23. #include <stdio.h>
  24.  
  25. float weight();
  26.  
  27.  
  28. setrotation(obj, tnum, angle, axis)
  29.     object_t *obj;
  30.     int tnum;
  31.     int angle;
  32.     char axis;
  33. {
  34.     obj->tlist[tnum].angle = angle;
  35.     switch(axis)
  36.     {
  37.     case 'x':
  38.         obj->tlist[tnum].type = ROTX;
  39.         break;
  40.     case 'y':
  41.         obj->tlist[tnum].type = ROTY;
  42.         break;
  43.     case 'z':
  44.         obj->tlist[tnum].type = ROTZ;
  45.         break;
  46.     default:
  47.         break;
  48.     }
  49. }
  50.  
  51.  
  52. setscale(obj, tnum, x, y, z)
  53.     object_t *obj;
  54.     int tnum;
  55.     float x, y, z;
  56. {
  57.     obj->tlist[tnum].type = SCALE;
  58.     obj->tlist[tnum].x = x;
  59.     obj->tlist[tnum].y = y;
  60.     obj->tlist[tnum].z = z;
  61. }
  62.  
  63.  
  64. settranslation(obj, tnum, x, y, z)
  65.     object_t *obj;
  66.     int tnum;
  67.     float x, y, z;
  68. {
  69.     obj->tlist[tnum].type = TRANSLATE;
  70.     obj->tlist[tnum].x = x;
  71.     obj->tlist[tnum].y = y;
  72.     obj->tlist[tnum].z = z;
  73. }
  74.  
  75.  
  76. /*
  77.  *  routines to generate normals for an object
  78.  */
  79. normalize(obj)
  80.     object_t *obj;
  81. {
  82.     int i;
  83.  
  84.     for (i=0; i < obj->gcount; i++)
  85.     {
  86.     switch(obj->glist[i].type)
  87.     {
  88.         case SSECTION:
  89.         ssect_norm(&obj->glist[i]);
  90.         break;
  91.         case FSECTION:
  92.         fsect_norm(&obj->glist[i]);
  93.         break;
  94.         case PSECTION:
  95.         case CSECTION:
  96.         case CDV_GEOM:
  97.         case CLS_GEOM:
  98.         case CDS_GEOM:
  99.         break;
  100.         default:
  101.         fprintf(stderr, "Error in normalizing \n");
  102.         break;
  103.     }
  104.     }
  105. }
  106.  
  107.  
  108. ssect_norm(sect)
  109.     geometry_t *sect;
  110. {
  111.     int i;
  112.     float nm;
  113.  
  114.     for (i=0; i < sect->vcount; i++)
  115.     {
  116.     sect->nlist[i][X] = 0.0;
  117.     sect->nlist[i][Y] = 0.0;
  118.     sect->nlist[i][Z] = 0.0;
  119.     }
  120.  
  121.     for (i=0; i < sect->pcount; i++)
  122.     spoly_norm(§->plist[i]);
  123.  
  124.     for (i=0; i < sect->vcount; i++)
  125.     {
  126.     if (sect->nlist[i][X] != 0.0 ||
  127.         sect->nlist[i][Y] != 0.0 ||
  128.         sect->nlist[i][Z] != 0.0)
  129.     {
  130.         nm = sqrt(sect->nlist[i][X] * sect->nlist[i][X] +
  131.               sect->nlist[i][Y] * sect->nlist[i][Y] +
  132.               sect->nlist[i][Z] * sect->nlist[i][Z]);
  133.  
  134.         sect->nlist[i][X] /= nm;
  135.         sect->nlist[i][Y] /= nm;
  136.         sect->nlist[i][Z] /= nm;
  137.     }
  138.     }
  139. }
  140.  
  141.  
  142. spoly_norm(p)
  143.     polygon_t *p;
  144. {
  145.     float px, py, pz, qx, qy, qz, nx, ny, nz, nm;
  146.     float w;
  147.     int i;
  148.  
  149.     /*
  150.      *  compute the normal
  151.      */
  152.     px = p->vlist[0][X] - p->vlist[1][X];
  153.     py = p->vlist[0][Y] - p->vlist[1][Y];
  154.     pz = p->vlist[0][Z] - p->vlist[1][Z];
  155.     qx = p->vlist[1][X] - p->vlist[2][X];
  156.     qy = p->vlist[1][Y] - p->vlist[2][Y];
  157.     qz = p->vlist[1][Z] - p->vlist[2][Z];
  158.     nx = py*qz - pz*qy;
  159.     ny = pz*qx - px*qz;
  160.     nz = px*qy - py*qx;
  161.  
  162.     /*
  163.      * normalize the normal to length 1
  164.      */
  165.     nm = sqrt(nx*nx + ny*ny + nz*nz);
  166.  
  167.     nx /= nm;
  168.     ny /= nm;
  169.     nz /= nm;
  170.  
  171.     w =  weight(p);
  172.     nx *= w;
  173.     ny *= w;
  174.     nz *= w;
  175.  
  176.     for (i=0; i < p->vcount; i++)
  177.     {
  178.     p->nlist[i][X] += nx;
  179.     p->nlist[i][Y] += ny;
  180.     p->nlist[i][Z] += nz;
  181.     }
  182. }
  183.  
  184.  
  185. float weight(p)
  186.     polygon_t *p;
  187. {
  188.     float xmax, ymax, zmax;
  189.     float xmin, ymin, zmin;
  190.     float dx, dy, dz;
  191.     int i;
  192.  
  193.     xmin = xmax = p->vlist[0][X];
  194.     ymin = ymax = p->vlist[0][Y];
  195.     zmin = zmax = p->vlist[0][Z];
  196.  
  197.     for (i=1; i < p->vcount; i++)
  198.     {
  199.     if (xmin > p->vlist[i][X])
  200.         xmin = p->vlist[i][X];
  201.     if (ymin > p->vlist[i][Y])
  202.         ymin = p->vlist[i][Y];
  203.     if (zmin > p->vlist[i][Z])
  204.         zmin = p->vlist[i][Z];
  205.     if (xmax < p->vlist[i][X])
  206.         xmax = p->vlist[i][X];
  207.     if (ymax < p->vlist[i][Y])
  208.         ymax = p->vlist[i][Y];
  209.     if (zmax < p->vlist[i][Z])
  210.         zmax = p->vlist[i][Z];
  211.     }
  212.  
  213.     dx = xmax - xmin;
  214.     dy = ymax - ymin;
  215.     dz = zmax - zmin;
  216.  
  217.     return (dx*dx + dy*dy + dz*dz);
  218. }
  219.  
  220.  
  221. fsect_norm(sect)
  222.     geometry_t *sect;
  223. {
  224.     int i;
  225.     float nm;
  226.  
  227.     for (i=0; i < sect->pcount; i++)
  228.     fpoly_norm(§->plist[i]);
  229. }
  230.  
  231.  
  232. fpoly_norm(p)
  233.     polygon_t *p;
  234. {
  235.     float px, py, pz, qx, qy, qz, nx, ny, nz, nm;
  236.     int i;
  237.  
  238.     /*
  239.      *  compute the normal
  240.      */
  241.     px = p->vlist[0][X] - p->vlist[1][X];
  242.     py = p->vlist[0][Y] - p->vlist[1][Y];
  243.     pz = p->vlist[0][Z] - p->vlist[1][Z];
  244.     qx = p->vlist[1][X] - p->vlist[2][X];
  245.     qy = p->vlist[1][Y] - p->vlist[2][Y];
  246.     qz = p->vlist[1][Z] - p->vlist[2][Z];
  247.     nx = py*qz - pz*qy;
  248.     ny = pz*qx - px*qz;
  249.     nz = px*qy - py*qx;
  250.  
  251.     /*
  252.      * normalize the normal to length 1
  253.      */
  254.     nm = sqrt(nx*nx + ny*ny + nz*nz);
  255.  
  256.     p->normal[X] = nx / nm;
  257.     p->normal[Y] = ny / nm;
  258.     p->normal[Z] = nz / nm;
  259. }
  260.  
  261.  
  262. compress(obj)
  263.     object_t *obj;
  264. {
  265.     int i;
  266.  
  267.     for (i=0; i < obj->gcount; i++)
  268.     g_compress(&obj->glist[i]);
  269. }
  270.  
  271.  
  272. g_compress(g)
  273.     geometry_t *g;
  274. {
  275.     polygon_t *p;
  276.     float **new_vlist;
  277.     float **new_nlist;
  278.     int new_vcount;
  279.     int *used, *loss;
  280.     int lost = 0;
  281.     int i, j;
  282.  
  283.     used = (int *)malloc(sizeof(int) * g->vcount);
  284.     loss = (int *)malloc(sizeof(int) * g->vcount);
  285.     bzero(used, sizeof(int) * g->vcount);
  286.  
  287.     for (i=0; i < g->pcount; i++)
  288.     {
  289.     p = &g->plist[i];
  290.         for (j=0; j < p->vcount; j++)
  291.         used[p->vnlist[j]] = TRUE;
  292.     }
  293.  
  294.     for (i=0; i < g->vcount; i++)
  295.     {
  296.     if (!used[i])
  297.     {
  298.         lost++;
  299.         free(g->vlist[i]);
  300.         if (g->nlist)
  301.             free(g->nlist[i]);
  302.     }
  303.     loss[i] = lost;
  304.     }
  305.  
  306.     if (!lost)
  307.     {
  308.         free(used);
  309.         free(loss);
  310.     return;
  311.     }
  312.  
  313.     new_vcount = g->vcount - lost;
  314.     new_vlist = (float **)malloc(sizeof(float *) * new_vcount);
  315.     if (g->nlist)
  316.         new_nlist = (float **)malloc(sizeof(float *) * new_vcount);
  317.     for (i=0, j=0; i < g->vcount; i++)
  318.     {
  319.     if (used[i])
  320.     {
  321.         new_vlist[j] = g->vlist[i];
  322.         if (g->nlist)
  323.             new_nlist[j] = g->nlist[i];
  324.         j++;
  325.     }
  326.     }
  327.  
  328.     g->vcount = new_vcount;
  329.  
  330.     free(g->vlist);
  331.     g->vlist = new_vlist;
  332.  
  333.     if (g->nlist)
  334.     {
  335.         free(g->nlist);
  336.         g->nlist = new_nlist;
  337.     }
  338.  
  339.     for (i=0; i < g->pcount; i++)
  340.     {
  341.     p = &g->plist[i];
  342.         for (j=0; j < p->vcount; j++)
  343.         p->vnlist[j] -= loss[p->vnlist[j]];
  344.     }
  345.  
  346.     free(used);
  347.     free(loss);
  348. }
  349.  
  350.  
  351. combine(obj)
  352.     object_t *obj;
  353. {
  354.     int i;
  355.  
  356.     for (i=0; i < obj->gcount; i++)
  357.     g_combine(&obj->glist[i]);
  358. }
  359.  
  360.  
  361. g_combine(g)
  362.     geometry_t *g;
  363. {
  364.     polygon_t *p;
  365.     int *use;
  366.     int i, j, k;
  367.  
  368.     use = (int *)malloc(sizeof(int) * g->vcount);
  369.     for (i=0; i < g->vcount; i++)
  370.         use[i] = -1;
  371.  
  372.     for (i=0; i < g->vcount; i++)
  373.     {
  374.     if (use[i] == -1)
  375.             for (j=i+1; j < g->vcount; j++)
  376.             if (g->vlist[i][X] == g->vlist[j][X] &&
  377.                 g->vlist[i][Y] == g->vlist[j][Y] &&
  378.                 g->vlist[i][Z] == g->vlist[j][Z] )
  379.             use[j] = i;
  380.     }
  381.  
  382.     for (i=0; i < g->pcount; i++)
  383.     {
  384.     p = &g->plist[i];
  385.         for (j=0; j < p->vcount; j++)
  386.     {
  387.         k = p->vnlist[j];
  388.         if (use[k] != -1)
  389.         {
  390.             p->vnlist[j] = use[k];
  391.             p->vlist[j] = g->vlist[use[k]];
  392.         if (g->nlist)
  393.                 p->nlist[j] = g->nlist[use[k]];
  394.         }
  395.     }
  396.     }
  397.  
  398.     free(use);
  399. }
  400.  
  401.  
  402. scale_obj(obj, x, y, z)
  403.     object_t *obj;
  404.     float x, y, z;
  405. {
  406.     geometry_t *g;
  407.     int i;
  408.  
  409.     for (i=0; i < obj->gcount; i++)
  410.         scale_g(&obj->glist[i], x, y, z);
  411. }
  412.  
  413. scale_g(g, x, y, z)
  414.     geometry_t *g;
  415.     float x, y, z;
  416. {
  417.     int i;
  418.  
  419.     for (i=0; i < g->vcount; i++)
  420.     {
  421.     g->vlist[i][X] *= x;
  422.     g->vlist[i][Y] *= y;
  423.     g->vlist[i][Z] *= z;
  424.     }
  425. }
  426.  
  427.  
  428. translate_obj(obj, x, y, z)
  429.     object_t *obj;
  430.     float x, y, z;
  431. {
  432.     geometry_t *g;
  433.     int i;
  434.  
  435.     for (i=0; i < obj->gcount; i++)
  436.         translate_g(&obj->glist[i], x, y, z);
  437. }
  438.  
  439.  
  440. translate_g(g, x, y, z)
  441.     geometry_t *g;
  442.     float x, y, z;
  443. {
  444.     int i;
  445.  
  446.     for (i=0; i < g->vcount; i++)
  447.     {
  448.     g->vlist[i][X] += x;
  449.     g->vlist[i][Y] += y;
  450.     g->vlist[i][Z] += z;
  451.     }
  452. }
  453.  
  454.  
  455. reverse_g(g)
  456.     geometry_t *g;
  457. {
  458.     polygon_t *p;
  459.     int i, j, tmp[200];
  460.  
  461.     for (i=0; i < g->pcount; i++)
  462.     {
  463.     p = &g->plist[i];
  464.     for (j=0; j < p->vcount; j++)
  465.         tmp[j] = p->vnlist[j];
  466.     for (j=0; j < p->vcount; j++)
  467.         p->vnlist[j] = tmp[(p->vcount-1)-j];
  468.     }
  469. }
  470.